package test.runtime2;

import java.util.List;
import java.util.Map;

import example.runner.Runner;

import materials.network.NetworkInterface;
import service.genetic.GeneticAlgorithm;
import service.genetic.NetworkGeneticService;
import visual.ValuePerTime;
import visual.VisualMatrix;

public class runtimeTest2{

	public static void main(String[] args){
		new runtimeTest2();
	}
	
	public runtimeTest2() {
		_netzvorlage = new RechenViehNetz2();
		_vpt1 = new ValuePerTime("name");
		_vpt1.setVisible(true);
		_vpt1.setAutoScale(true);
	//	_vm = new VisualMatrix();
		//_vm.setVisible(true);
		createPopulation();
		startEvolution(1000000);
	}

	Rechenvieh2[] _viecher;
	RechenViehNetz2 _netzvorlage;
	private final int VIECHER_COUNT = 200;

	ValuePerTime _vpt1;
	//VisualMatrix _vm;

	public void createPopulation() {
		_viecher = new Rechenvieh2[VIECHER_COUNT];
		for(int i = 0; i < VIECHER_COUNT; i++){
			_viecher[i] = new Rechenvieh2(_netzvorlage.getNet());
		}
	}

	private double[] generateInpVect(){
		double[] vect = new double[1];
		for(int i = 0; i < vect.length; i++){
			vect[i] = (int)(Math.random() *8 +1);
		}
		return vect;
	}
	

	public void startEvolution(int generations) {
		for(int i = 0; i < generations; i++){
			
			for( int run = 0; run < 100; run++){
				double[] inp = generateInpVect();
				
				for(Rechenvieh2 rv : _viecher){
					rv.calculateInput(inp);
				}
			}
			sort();
			//System.out.println(_viecher[0].getFitness());
			_vpt1.addData((int)((_viecher[0].getFehler())));
			if(_viecher[0].getFehler() < 5){
				_viecher[0].getNet().getWeigthMatrix(1).printMatrix();
			}
			//_viecher[0].getNet().getWeigthMatrix(1).printMatrix(";a;b", ";c;d");
			//_vm.updateGUI(_viecher[0].getNet());
			createNextGen();
		}
	}
	
	NetworkGeneticService ngs = new NetworkGeneticService();
	
	private void createNextGen() {
		_viecher[0].getNet().getWeigthMatrix(1).printMatrix();
		Rechenvieh2[] temp = new Rechenvieh2[VIECHER_COUNT];
		temp[0] = _viecher[0];
		temp[1] = _viecher[1];
		int z  = 2;
		 
		while(z < VIECHER_COUNT){
			int a = (int)(Math.random()*(5.0));
			int b = (int)(Math.random()*(3.0));
			Rechenvieh2 r = new Rechenvieh2(_netzvorlage.getNet());
			ngs.recombineNetworks(_viecher[a].getNet(), _viecher[b].getNet());
			ngs.mutateNetwork(r.getNet(), 0.01, 0.01);
			ngs.CrossOverNetwork(r.getNet(), 0.001, 1);
			temp[z] = r;
			z++;
		}
		_viecher = temp;
	}

	private void sort(){
		for (int j = 0; j < VIECHER_COUNT; j++)
		{
			for (int i = j; i < VIECHER_COUNT; i++)
			{
				if (_viecher[i].getFitness() > _viecher[j].getFitness())
				{
					Rechenvieh2 r = _viecher[i];
					_viecher[i] = _viecher[j];
					_viecher[j] = r;
				}
			}
		}

	}
}
